package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.protocol.Common.PBUserData;
import com.motu.monstercity.protocol.CsGameCave.PBCaveEnemy;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.base.CommonUtils;
import com.motu.monstercity.server.game.base.ProtoDataUtils;
import com.motu.monstercity.server.game.commondata.build.BuildConstant;
import com.motu.monstercity.server.game.commondata.cave.CaveConstant;
import com.motu.monstercity.server.game.commondata.cave.CaveMain;
import com.motu.monstercity.server.game.commondata.maintask.MainTaskConstant;
import com.motu.monstercity.server.game.commondata.rank.RankConstant;
import com.motu.monstercity.server.game.log.LogType;
import com.motu.monstercity.server.game.log.ThinkingDataManager;
import com.motu.monstercity.server.game.userdata.*;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.json.JsonArray;

import java.util.ArrayList;
import java.util.List;

public class CaveManager extends CaveUserData {
    // 初始化 下发怪兽洞窟模块的用户数据
    public static void loadInitCaveUserData(PBUserData.Builder pbUserData, UserInfo userInfo) {
        long userId = userInfo.getId();
        UserCaveLocation userCaveLocation = getUserCaveLocation(userId);
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveLocation, true);
        UserCaveInfo userCaveInfo = getUserCaveInfo(userId);
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveInfo, true);
    }


    // 获取我的对手列表
    public static List<PBCaveEnemy.Builder> getCaveEnemyList(CaveMain caveMain, int serverId) {
        List<PBCaveEnemy.Builder> list = new ArrayList<>();
        if (caveMain == null) {
            return list;
        }
        JsonArray jsonArray = getCaveMainIdList(caveMain);
        for (int i=0; i<jsonArray.size(); i++) {
            CaveMain entity = getCaveMain(jsonArray.getInteger(i));
            PBCaveEnemy.Builder pbCaveEnemy = PBCaveEnemy.newBuilder();
            pbCaveEnemy.setCaveMainId(entity.getId());
            ServerCaveLocation serverCaveLocation = getServerCaveLocation(serverId, entity.getCaveKey());
            if (serverCaveLocation != null && serverCaveLocation.getUserId() > 0) {
                pbCaveEnemy.setServerCaveLocation(serverCaveLocation.takeInitBuilder());
            }
            list.add(pbCaveEnemy);
        }

        return list;
    }

    // 获取对手的坑位列表 caveMainId列表
    public static JsonArray getCaveMainIdList(CaveMain caveMainMy) {
        JsonArray jsonArray = new JsonArray();// 对手的坑位列表
        int maxEneym = getMaxEnemy(caveMainMy);
        if (isAreaTopFloor(caveMainMy)) {// 是否达到本区域的最顶层
            int areaTypeNext = caveMainMy.getAreaType() + 1;
            if (areaTypeNext <= AllParam.CAVE_MAX_SERVER_AREA) {
                jsonArray = getBottomList(areaTypeNext);// 取下个区域的 非滞留层的最后5个坑位
            }
        } else {
            jsonArray = getCaveMainIdList(caveMainMy.getAreaType(), caveMainMy.getFloorId(), maxEneym);
        }
        return jsonArray;
    }

    // pve时校验目标坑位是否可以打，目标是1-4区域
    public static boolean checkEnemyPVE(CaveMain caveMainMy, CaveMain caveMainTarget) {
        JsonArray jsonArray = getCaveMainIdList(caveMainMy);
        if (Tool.isInList(jsonArray, caveMainTarget.getId())) {
            return true;
        } else {
            return false;
        }
    }

    // 校验这个对手是否可以打
    public static boolean checkEnemyPVP(CaveMain caveMainMy, CaveMain caveMainTarget, ServerCaveLocation serverCaveLocationTarget, long enemyId) {
        if (!checkEnemyPVE(caveMainMy, caveMainTarget)) {
            return false;
        }

        if (serverCaveLocationTarget == null || serverCaveLocationTarget.getUserId() == enemyId) {
            return true;//pvp区域，该坑位没有玩家，或是=enemyId才可以打
        }
        return false;
    }

    // 获取对方的战力
    public static long getEnemyPower(CaveMain caveMainTarget, ServerCaveLocation serverCaveLocationTareget) {
        if (serverCaveLocationTareget != null && serverCaveLocationTareget.getPower() > 0) {
            return serverCaveLocationTareget.getPower();
        } else {
            return caveMainTarget.getMonsterPower();
        }
    }

    // 生成战报
    public static void createCaveRecord(long userId, long enemyId, String userName, int result, int areaType, int floorId, int floorIdNew) {
        UserCaveRecord userCaveRecord = new UserCaveRecord(userId, enemyId, userName, result, areaType, floorId, floorIdNew);
        userCaveRecord.doCreate();
    }

    // 更新怪兽洞窟的排行榜
    public static void updateCaveRank(int serverId, long userId, CaveMain caveMain) {
        if (caveMain.getAreaType() == CaveConstant.AREA_TYPE_6) {// 只有打区域6的才会写入排行榜
            int score = caveMain.getFloorId();// floorid越大，排名越前面
            RankManager.updateRank(RankConstant.SERVER_RANK_CAVE, serverId, userId, score, "0");
        }
    }

    // 最多显示几个对手， 在前一区域第一名的人，才看到5个对手，其他的最多显示4个
    public static int getMaxEnemy(CaveMain caveMainMy) {
        if (isAreaTopFloor(caveMainMy)) {
            return AllParam.CAVE_LOCATION_MAX[1];
        } else {
            return AllParam.CAVE_LOCATION_MAX[0];
        }
    }

    // 当前是否在这个区域的第一名
    public static boolean isAreaTopFloor(CaveMain caveMainMy) {
        CaveMain caveMain = getTopFloorByAreaType(caveMainMy.getAreaType());
        if (caveMain == null) {
            return false;
        }
        if (caveMainMy.getFloorId() == caveMain.getFloorId()) {
            return true;
        } else {
            return false;
        }
    }

    // 发放首次达层奖励
    public static void sendOnceReward(PBUserData.Builder pbUserData, UserInfo userInfo, UserCaveInfo userCaveInfo, CaveMain caveMainTarget, long curPower) {
        CaveMain caveMain = null;
        int startId = userCaveInfo.getOnceRewardId()+1;
        for (int i=startId;i<=caveMainTarget.getId();i++) {
            caveMain = getCaveMain(i);
            if (caveMain != null && !Tool.isEmpty(caveMain.getOnceReward())) {
                RewardManager.addReward(userInfo, CommonUtils.takeReawrdItemFromStr(caveMain.getOnceReward()), pbUserData, LogType.CAVE_ONCE_REWARD, caveMain.getId() + "_" + curPower);// 获得相应奖励
            }
        }

        userCaveInfo.putOnceRewardId(caveMainTarget.getId());
        userCaveInfo.update();
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveInfo);
    }

    // pve 胜利
    public static void handlePVESucc(PBUserData.Builder pbUserData, UserInfo userInfo, UserPower userPower, long curPower, UserCaveLocation userCaveLocation, UserCaveInfo userCaveInfo, CaveMain caveMainTarget) {
        userCaveLocation.putAreaType(caveMainTarget.getAreaType());
        userCaveLocation.putFloorId(caveMainTarget.getFloorId());
        userCaveLocation.updateEarnAdd(pbUserData, userInfo, userPower);// 地下洞窟更新时，批量更新商业建筑的收益
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveLocation);
        sendOnceReward(pbUserData, userInfo, userCaveInfo, caveMainTarget, curPower);// 发放首次达层奖励

        ThinkingDataManager.pushUserCaveEvent(userInfo, caveMainTarget);// 数数上报数据
    }

    // pvp胜利 打5-6层时交换位置，修改对方的usercavelocation数据
    public static void handlePVPSucc(PBUserData.Builder pbUserData, UserInfo userInfo, UserCaveLocation userCaveLocation, UserPower userPower, long myPower, CaveMain caveMainMy, CaveMain caveMainTarget, ServerCaveLocation locationTarget, long enemyId) {
        long useridTarget = 0L;
        String userNmaeTarget = "";
        long powerTarget = 0L;
        String partnerTarget = "";// 伙伴快照
        String iconTarget = "";

        // 我换到对方的坑位去
        boolean isCreate = false;// 是否新建
        if (locationTarget == null) {
            locationTarget = new ServerCaveLocation();
            isCreate = true;
        } else {
            useridTarget = locationTarget.getUserId();
            userNmaeTarget = locationTarget.getUserName();
            powerTarget = locationTarget.getPower();
            partnerTarget = locationTarget.getPartner();
            iconTarget = locationTarget.getIcon();
        }
        locationTarget.putServerId(userInfo.getServerId());
        locationTarget.putLocationId(caveMainTarget.getCaveKey());
        locationTarget.putUserId(userInfo.getId());
        locationTarget.putUserName(userInfo.getUserName());
        locationTarget.putPower(myPower);// 我的总战力，地下矿洞
        locationTarget.putIcon(userInfo.getIcon());
        locationTarget.putPartner(PartnerManager.createPartnerPhoto(userInfo.getId(), userPower));
        if (isCreate) {
            locationTarget.doCreate();
        } else {
            locationTarget.update();
        }

        userCaveLocation.putAreaType(caveMainTarget.getAreaType());
        userCaveLocation.putFloorId(caveMainTarget.getFloorId());// 地下洞窟更新时，批量更新商业建筑的收益
        userCaveLocation.updateEarnAdd(pbUserData, userInfo, userPower);
        ProtoDataUtils.updatePBUserData(pbUserData, userCaveLocation);

        int serverId = userInfo.getServerId();
        ServerCaveLocation serverCaveLocationMy = getServerCaveLocation(serverId, caveMainMy.getCaveKey());
        boolean isClear = false;// 是否清空我之前的坑位的信息，对手是怪兽，或者我是5区域第一名，跨区域挑战时
        if (enemyId > 0) {// 对手是玩家， 那把对方换到我原来的坑位
            UserCaveLocation userCaveLocationTarget = getUserCaveLocation(enemyId);
            if (caveMainMy.getAreaType() < caveMainTarget.getAreaType() || caveMainMy.isBottomFloor()) {// 跨区域挑战,或我原来是滞留层，对方退到滞留层, 不需要创建serverCaveLocation
                userCaveLocationTarget.putFloorId(getBottomFloorByAreaType(userCaveLocationTarget.getAreaType()).getFloorId());
                isClear = true;
            } else {// 同区域挑战，需要交换serverCaveLocation
                userCaveLocationTarget.putFloorId(caveMainMy.getFloorId());

                serverCaveLocationMy.putUserId(useridTarget);
                serverCaveLocationMy.putUserName(userNmaeTarget);
                serverCaveLocationMy.putPower(powerTarget);
                serverCaveLocationMy.putIcon(iconTarget);
                serverCaveLocationMy.putPartner(partnerTarget);
                serverCaveLocationMy.update();
            }
            userCaveLocationTarget.update();
            UserInfo userInfoTarget = GameUser.getUserInfo(enemyId);
            UserPower userPowerTarget = GameUser.getUserPower(enemyId);
            CaveManager.updateEarn(null, userInfoTarget, userPowerTarget, userCaveLocationTarget);// 根据对手的坑位更新城对手市收益的加成
            updateCaveRank(serverId, enemyId, caveMainMy);// 更新对手的榜单


            // 给对手生成战报
            int recordResult = 1;// 对手输了，
            createCaveRecord(enemyId, userInfo.getId(), userInfo.getUserName(), 1, caveMainTarget.getAreaType(), caveMainTarget.getFloorId(), caveMainMy.getFloorId());
        } else {// 对手是怪兽， 把我原来的坑位数据清掉
            isClear = true;
        }


        // 清空我之前的坑位的信息，对手是怪兽，或者我是5区域第一名，跨区域挑战时
        if (isClear && serverCaveLocationMy != null) {
            serverCaveLocationMy.putUserId(0);
            serverCaveLocationMy.putUserName("");
            serverCaveLocationMy.putPower(0);
            serverCaveLocationMy.putPartner("");
            serverCaveLocationMy.putIcon("");
            serverCaveLocationMy.update();
        }

        ThinkingDataManager.pushUserCaveEvent(userInfo, caveMainTarget);// 数数上报数据
    }

    // 是否需要 按服加锁, 我在4区域第一名，或是5区域的底部5名，或是5区域的第1名，或是6区域的底部5名时，需要全服加锁
    public static boolean isLockServer(CaveMain caveMainMy) {
        if (isAreaTopFloor(caveMainMy)) {// 4区域的第一名，5区域的第一名
            return true;
        } else {
            JsonArray jsonArray = getBottomList(caveMainMy.getAreaType());// 取该区域底部的5层
            if (Tool.isInList(jsonArray, caveMainMy.getFloorId())) {
                return true;
            } else {
                return false;
            }
        }
    }

    // 根据坑位更新城市收益的加成

    public static void updateEarn(PBUserData.Builder pbUserData, UserInfo userInfo, UserPower userPower, UserCaveLocation userCaveLocation) {
        if (userCaveLocation == null) {
            return;
        }
        userPower.updateEarnAddCave(pbUserData, userInfo, userCaveLocation.takeEarnAdd());
    }
}
